package com.googlecode.grima.service;

import java.util.ArrayList;
import java.util.List;

import org.activiti.engine.IdentityService;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.googlecode.grima.base.GenericDao;
import com.googlecode.grima.base.GenericEntityService;
import com.googlecode.grima.base.GenericEntityServiceImpl;
import com.googlecode.grima.base.Page;
import com.googlecode.grima.base.SearchResult;
import com.googlecode.grima.base.SearchTemplate;
import com.googlecode.grima.dao.GroupDao;
import com.googlecode.grima.domain.Group;

@Service("groupService")
public class GroupService extends GenericEntityServiceImpl<Group, Long> implements GenericEntityService<Group, Long> {

	protected GroupDao groupDao;
	protected IdentityService identityService;

	@Autowired
	public void setGroupDao(GroupDao groupDao) {
		this.groupDao = groupDao;
	}

	@Autowired
	public void setIdentityService(IdentityService identityService) {
		this.identityService = identityService;
	}
	
	@Override
	public GenericDao<Group, Long> getDao() {
		return groupDao;
	}

	@Override
	public Group getNew() {
		return new Group();
	}

	@Override
	public Group getNewWithDefaults() {
		return getNew();
	}

	@Transactional
	@Override
	public void save(Group group) {
		org.activiti.engine.identity.Group activitiGroup = identityService.createGroupQuery().groupId(group.getName()).singleResult();
		if (activitiGroup == null){
			activitiGroup = identityService.newGroup(group.getName());
		}
		activitiGroup.setType(group.getType());
		activitiGroup.setName(group.getName());
		identityService.saveGroup(activitiGroup);
		super.save(group);
	}

	public SearchResult<Group, Long> findAll(Page page){
		SearchResult<Group, Long> ret = new SearchResult<Group, Long>();
		
		int pageNumber = page.getPageNumber();
		int pageSize = page.getPageSize();
		
    SearchTemplate searchTemplate = new SearchTemplate();
    int firstResult = ((pageNumber-1) * pageSize);
    searchTemplate.setFirstResult(firstResult);
    searchTemplate.setMaxResults(pageSize);
		List<Group> groups = find(searchTemplate);
		int count = findCount(searchTemplate);

		ret.setTotal(count);
		ret.setRows(groups);
		
		return ret;
	}

	public String[] findAllNames(){
		List<Group> list = find();
		List<String> ret = new ArrayList<String>();
		for (Group group : list) {
			String name = group.getName();
			ret.add(name);
    }
		return ret.toArray(new String[ret.size()]);
	}	
	
	public Group findById(Long id){
		Group group = getByPrimaryKey(id);
		return group;
	}
	
	public SearchResult<Group, Long> findByParameters(String name, String description, String type, Page page) {
		SearchResult<Group, Long> ret = new SearchResult<Group, Long>();
		
		int pageNumber = page.getPageNumber();
		int pageSize = page.getPageSize();
		
    SearchTemplate searchTemplate = new SearchTemplate();
    int firstResult = ((pageNumber-1) * pageSize);
    searchTemplate.setFirstResult(firstResult);
    searchTemplate.setMaxResults(pageSize);
    
    if (StringUtils.isNotEmpty(name)){
    	searchTemplate.addCriterion(Restrictions.like("name", "%"+name+"%"));
    }

    if (StringUtils.isNotEmpty(description)){
    	searchTemplate.addCriterion(Restrictions.like("description", "%"+description+"%"));
    }

    if (StringUtils.isNotEmpty(type)){
    	searchTemplate.addCriterion(Restrictions.like("type", "%"+type+"%"));
    }

		List<Group> groups = find(searchTemplate);
		int count = findCount(searchTemplate);

		ret.setTotal(count);
		ret.setRows(groups);
		
		return ret;
  }
	
	public void deleteById(Long id){
		Group group = getByPrimaryKey(id);
		deleteByPrimaryKey(id);
		identityService.deleteGroup(group.getName());
	}
	
	public String[] findUserGroups(String login){
		List<org.activiti.engine.identity.Group> list = identityService.createGroupQuery().groupMember(login).list();
		List<String> ret = new ArrayList<String>();
		for (org.activiti.engine.identity.Group group : list) {
			String id = group.getId();
			ret.add(id);
    }
		return ret.toArray(new String[ret.size()]);
	}
	
}
